#include "stdafx.h"
#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

#include "forward_list.h"

namespace UnitTestForwardList
{		
	TEST_CLASS(UnitTestForwardList)
	{
	public:
		
		TEST_METHOD(TestForwardList_is_empty)
		{
			forward_list<int> fli;

			Assert::AreEqual(true, fli.is_empty() );
		}

		TEST_METHOD(TestForwardList_push_front_and_front)
		{
			

			forward_list<int> fli;

			int x = 10;
			fli.push_front(x);
			Assert::AreEqual(fli.front(), 10);

			x = 20;
			fli.push_front(x);
			Assert::AreEqual(fli.front(), 20);

			x = 30;
			fli.push_front(x);
			Assert::AreEqual(fli.front(), 30);

		}

		TEST_METHOD(TestForwardList_iterator_begin_end)
		{
			forward_list<int> fli;

			int x = 1;
			fli.push_front(x);
			x = 2;
			fli.push_front(x);
			x = 3;
			fli.push_front(x);

			int i = 3;

			for (auto it = fli.begin(); it != fli.end(); it++){
				Assert::AreEqual(i, it->value);
				i--;
			}

			//for (auto &n : fli){}

		}

		TEST_METHOD(TestForwardList_pop_front)
		{
			forward_list<int> fli;

			int x = 10;
			fli.push_front(x);
			x = 20;
			fli.push_front(x);
			x = 30;
			fli.push_front(x);

			Assert::AreEqual(fli.front(), 30);
			fli.pop_front();
			Assert::AreEqual(fli.front(), 20);
			fli.pop_front();
			Assert::AreEqual(fli.front(), 10);
			fli.pop_front();
			Assert::AreEqual(true, fli.is_empty());

		}

		TEST_METHOD(TestForwardList_size)
		{
			forward_list<int> fli;

			int x = 10;
			fli.push_front(x);
			x = 20;
			fli.push_front(x);
			x = 30;
			fli.push_front(x);

			Assert::AreEqual(3, fli.size());

			x = 40;
			fli.push_front(x);

			Assert::AreEqual(4, fli.size());

			fli.pop_front();
			fli.pop_front();
			fli.pop_front();
			fli.pop_front();

			Assert::AreEqual(0, fli.size());
		}

		TEST_METHOD(TestForwardList_clear)
		{
			forward_list<int> fli;

			int x = 10;
			fli.push_front(x);
			x = 20;
			fli.push_front(x);
			x = 30;
			fli.push_front(x);

			Assert::AreEqual(3, fli.size());

			fli.clear();

			Assert::AreEqual(0, fli.size());

			Assert::AreEqual(true, fli.is_empty());
		}

		TEST_METHOD(TestForwardList_erase_after)
		{
			forward_list<int> fli;

			int x = 10;
			fli.push_front(x);
			x = 20;
			fli.push_front(x);
			x = 30;
			fli.push_front(x);
			x = 40;
			fli.push_front(x);

			Assert::AreEqual(4, fli.size());

			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(30, fli.value_at_position(1));
			Assert::AreEqual(20, fli.value_at_position(2));
			Assert::AreEqual(10, fli.value_at_position(3));


			fli.erase_after(1);

			Assert::AreEqual(3, fli.size());

			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(30, fli.value_at_position(1));
			Assert::AreEqual(10, fli.value_at_position(2));

			fli.erase_after(0);

			Assert::AreEqual(2, fli.size());

			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(10, fli.value_at_position(1));


		}

		TEST_METHOD(TestForwardList_insert_after)
		{
			forward_list<int> fli;

			int x = 10;
			fli.push_front(x);
			x = 20;
			fli.push_front(x);
			x = 30;
			fli.push_front(x);
			x = 40;
			fli.push_front(x);

			Assert::AreEqual(4, fli.size());

			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(30, fli.value_at_position(1));
			Assert::AreEqual(20, fli.value_at_position(2));
			Assert::AreEqual(10, fli.value_at_position(3));

			fli.insert_after(1,25);

			Assert::AreEqual(5, fli.size());

			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(30, fli.value_at_position(1));
			Assert::AreEqual(25, fli.value_at_position(2));
			Assert::AreEqual(20, fli.value_at_position(3));
			Assert::AreEqual(10, fli.value_at_position(4));

			fli.insert_after(0, 35);

			Assert::AreEqual(6, fli.size());

			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(35, fli.value_at_position(1));
			Assert::AreEqual(30, fli.value_at_position(2));
			Assert::AreEqual(25, fli.value_at_position(3));
			Assert::AreEqual(20, fli.value_at_position(4));
			Assert::AreEqual(10, fli.value_at_position(5));

			fli.insert_after(5, 5);

			Assert::AreEqual(7, fli.size());

			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(35, fli.value_at_position(1));
			Assert::AreEqual(30, fli.value_at_position(2));
			Assert::AreEqual(25, fli.value_at_position(3));
			Assert::AreEqual(20, fli.value_at_position(4));
			Assert::AreEqual(10, fli.value_at_position(5));
			Assert::AreEqual(5, fli.value_at_position(6));

		}

		TEST_METHOD(TestForwardList_swap)
		{
			forward_list<int> fli;

			int x = 10;
			fli.push_front(x);
			x = 20;
			fli.push_front(x);
			x = 30;
			fli.push_front(x);
			x = 40;
			fli.push_front(x);


			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(30, fli.value_at_position(1));
			Assert::AreEqual(20, fli.value_at_position(2));
			Assert::AreEqual(10, fli.value_at_position(3));

			fli.swap(1,2);
			
			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(20, fli.value_at_position(1));
			Assert::AreEqual(30, fli.value_at_position(2));
			Assert::AreEqual(10, fli.value_at_position(3));

			fli.swap(1,3);

			Assert::AreEqual(40, fli.value_at_position(0));
			Assert::AreEqual(10, fli.value_at_position(1));
			Assert::AreEqual(30, fli.value_at_position(2));
			Assert::AreEqual(20, fli.value_at_position(3));

			fli.swap(0,3);

			Assert::AreEqual(20, fli.value_at_position(0));
			Assert::AreEqual(10, fli.value_at_position(1));
			Assert::AreEqual(30, fli.value_at_position(2));
			Assert::AreEqual(40, fli.value_at_position(3));

			fli.swap(0,0);

			Assert::AreEqual(20, fli.value_at_position(0));
			Assert::AreEqual(10, fli.value_at_position(1));
			Assert::AreEqual(30, fli.value_at_position(2));
			Assert::AreEqual(40, fli.value_at_position(3));

			fli.swap(2,2);

			Assert::AreEqual(20, fli.value_at_position(0));
			Assert::AreEqual(10, fli.value_at_position(1));
			Assert::AreEqual(30, fli.value_at_position(2));
			Assert::AreEqual(40, fli.value_at_position(3));
	

		}

		TEST_METHOD(TestForwardList_copy_constructor)
		{
			forward_list<int> fli;

			

			int x = 10;
			fli.push_front(x);
			x = 20;
			fli.push_front(x);
			x = 30;
			fli.push_front(x);

			forward_list<int> fli2(fli);
			Assert::AreEqual(3, fli2.size());

			Assert::AreEqual(30, fli.value_at_position(0));
			Assert::AreEqual(20, fli.value_at_position(1));
			Assert::AreEqual(10, fli.value_at_position(2));

			Assert::AreEqual(30, fli2.value_at_position(0));
			Assert::AreEqual(20, fli2.value_at_position(1));
			Assert::AreEqual(10, fli2.value_at_position(2));

			fli.clear();

			Assert::AreEqual(3, fli2.size());

			Assert::AreEqual(30, fli2.value_at_position(0));
			Assert::AreEqual(20, fli2.value_at_position(1));
			Assert::AreEqual(10, fli2.value_at_position(2));


		}

		

		TEST_METHOD(TestForwardList_assignment_operator)
		{
			forward_list<int> fli;



			int x = 10;
			fli.push_front(x);
			x = 20;
			fli.push_front(x);
			x = 30;
			fli.push_front(x);

			forward_list<int> fli2;

			fli2 = fli;

			Assert::AreEqual(3, fli2.size());

			Assert::AreEqual(30, fli.value_at_position(0));
			Assert::AreEqual(20, fli.value_at_position(1));
			Assert::AreEqual(10, fli.value_at_position(2));

			Assert::AreEqual(30, fli2.value_at_position(0));
			Assert::AreEqual(20, fli2.value_at_position(1));
			Assert::AreEqual(10, fli2.value_at_position(2));

			fli.clear();

			Assert::AreEqual(3, fli2.size());

			Assert::AreEqual(30, fli2.value_at_position(0));
			Assert::AreEqual(20, fli2.value_at_position(1));
			Assert::AreEqual(10, fli2.value_at_position(2));


		}


	};
}